package com.ufgov.smartclient.component.table;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.AbstractListModel;

/**
 * <p>Title: com.ufgov.smartclient.component</p>
 * <p>Description: TableRowHeader继承自JList，
 * 但ListMode在一些功能上不能满足需要，该类对其做了一些增强</p>
 * <p>Copyright: Copyright 2009 ufgov, Inc.</p>
 * <p>Company: ufgov</p>
 * <p>创建时间: 2009-4-14</p>
 * @author 刘永伟(manlge)
 * @version 1.0
 */
public class TableRowHeaderListModel extends AbstractListModel {

  /**
   * 选择状态列表，用来保存行是否被勾选，第一行是一个boolean对象，true代表被钩选
   */
  private List<Boolean> statList = new Vector<Boolean>();

  /**
   * 所属表格组件
   */
  private JGroupableTable table;

  public TableRowHeaderListModel(final TableRowHeader header) {
    this.table = header.getTable();
    table.addPropertyChangeListener("model", new PropertyChangeListener() {

      @Override
      public void propertyChange(PropertyChangeEvent evt) {
        updateElements();
        installTableModeListener();
      }
    });
    installTableModeListener();
  }

  /**
   * 安装tableMode监听器
   */
  private void installTableModeListener() {
    //    table.getModel().addTableModelListener(new TableModelListener() {
    //
    //      @Override
    //      public void tableChanged(TableModelEvent e) {
    //        if (e.getColumn() == TableModelEvent.ALL_COLUMNS) {
    //          if (e.getType() == TableModelEvent.INSERT) {
    //            //表格插入行时执行插入操作
    //            statList.add(e.getLastRow(), false);
    //          } else if (e.getType() == TableModelEvent.DELETE) {
    //            //表格删除行时同步删除
    //            statList.remove(e.getLastRow());
    //          } else if ((e.getFirstRow() == e.getLastRow())
    //            && e.getFirstRow() == TableModelEvent.HEADER_ROW) {
    //            updateElements();
    //          } else if (e.getType() == TableModelEvent.UPDATE
    //            && e.getColumn() == TableModelEvent.ALL_COLUMNS
    //            && e.getFirstRow() == 0 && e.getLastRow() == Integer.MAX_VALUE) {
    //            //调用了fireTableDataChanged
    //            updateElements();
    //          }
    //        }
    //      }
    //    });
    table.addPropertyChangeListener("totalLineModel", new PropertyChangeListener() {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
        updateElements();
      }
    });
  }

  /**
   * 根据tableMode重新生成statList
   */
  protected void updateElements() {
    statList.clear();
    for (int i = 0; i < table.getRowCount(); i++) {
      statList.add(false);
    }
    if (table.getTotalLineModel() != null) {
      statList.add(false);
    }
  }

  public int getSize() {
    return statList.size();
  }

  /**
   * @param index
   * @return 指定行是否被选定
   * @see TableRowHeaderListModel#setChecked(int, boolean)
   */
  public boolean isChecked(int index) {
    if (index >= table.getRowCount())
      return false;
    if (index < 0 || index >= statList.size()) {
      return false;
    }

    return statList.get(index);
  }

  /**
   * 设置index行是否被钩选
   * @param index
   * @param b
   * @see TableRowHeaderListModel#isChecked(int)
   */
  void setChecked(int index, boolean b) {
    if (index >= table.getRowCount())
      return;
    int idx = index;
    Boolean old = statList.get(idx);
    if (old.equals(b))
      return;
    statList.set(idx, b);
    fireContentsChanged(this, index, index);
  }

  @Override
  public void fireContentsChanged(Object source, int index0, int index1) {
    super.fireContentsChanged(source, index0, index1);
  }

  /**
   * @return 所有已勾选的行
   * @see TableRowHeaderListModel#setChecked(int, boolean)
   */
  public Integer[] getCheckedRows() {
    List<Integer> l = new ArrayList<Integer>();
    for (int i = 0; i < getSize(); i++) {
      if ((isChecked(i))) {
        l.add(i);
      }
    }
    if (l.size() < 1) {
      return new Integer[] {};
    } else {
      return l.toArray(new Integer[] { l.size() });
    }
  }

  /**
   * 全选行所有
   * @see TableRowHeaderListModel#getCheckedRows()
   */
  public void checkedAllRows() {
    for (int i = 0; i < getSize(); i++) {
      if (!(Boolean) getElementAt(i)) {
        setChecked(i, true);
        fireContentsChanged(this, i, i);
      }
    }
  }

  /**
   * 取消构选所有行
   * @see TableRowHeaderListModel#getCheckedRows()
   * @see #checkedAllRows()
   * @see #setChecked(int, boolean)
   */
  public void uncheckedAllRows() {
    for (int i = 0; i < getSize(); i++) {
      if ((Boolean) getElementAt(i)) {
        setChecked(i, false);
        fireContentsChanged(this, i, i);
      }
    }
  }

  @Override
  public Object getElementAt(int index) {
    return isChecked(index);
  }
}
